using System;
using System.Data;
using System.Data.OleDb;
using System.Reflection;
using C1.Win.C1Preview;
using PCSUtils.Utils;

namespace BangKeChiTietVatLieuChinhItem
{
	[Serializable]
	public class BangKeChiTietVatLieuChinhItem : MarshalByRefObject, IDynamicReport
	{
		public BangKeChiTietVatLieuChinhItem()
		{
		}

		private string mConnectionString;
		private ReportBuilder mReportBuilder;
		private C1PrintPreviewControl mReportViewer;
		private object mResult;

		/// <summary>
		/// ConnectionString, provide for the Dynamic Report
		/// ALlow Dynamic Report to access the DataBase of PCS
		/// </summary>
		public string PCSConnectionString
		{
			get { return mConnectionString; }
			set { mConnectionString = value; }
		}

		/// <summary>
		/// Report Builder Utility Object
		/// Dynamic Report can use this object to render, modify, layout the report
		/// </summary>
		public ReportBuilder PCSReportBuilder
		{
			get { return mReportBuilder; }
			set { mReportBuilder = value; }
		}

		/// <summary>
		/// ReportViewer Object, provide for the DynamicReport, 
		/// allow Dynamic Report to manipulate with the REportViewer, 
		/// modify the report after rendered if needed
		/// </summary>
		public C1PrintPreviewControl PCSReportViewer
		{
			get { return mReportViewer; }
			set { mReportViewer = value; }
		}

		/// <summary>
		/// Store other result if any. Ussually we store return DataTable here to display on the ReportViewer Form's Grid
		/// </summary>
		public object Result
		{
			get { return mResult; }
			set { mResult = value; }
		}

		private bool mUseReportViewerRenderEngine = true;

		/// <summary>
		/// Notify PCS whether the rendering report process is run by
		/// this IDynamicReport or the ReportViewer Engine (in the ReportViewer form)
		/// </summary>
		public bool UseReportViewerRenderEngine
		{
			get { return mUseReportViewerRenderEngine; }
			set { mUseReportViewerRenderEngine = value; }
		}

		private string mstrReportDefinitionFolder = string.Empty;
		/// <summary>
		/// Inform External Process where to find out the ReportLayout	 ( the PCS' ReportDefinition Folder Path )
		/// </summary>				
		public string ReportDefinitionFolder
		{
			get { return mstrReportDefinitionFolder; }
			set { mstrReportDefinitionFolder = value; }
		}


		private string mstrReportLayoutFile = string.Empty;		
		/// <summary>
		/// Inform External Process about the Layout file
		/// in which PCS instruct to use
		/// (PCS will assign this property while ReportViewer Form execute,
		/// ReportVIewer form will use the layout file in the report config entry to put in this property)
		/// </summary>		
		public string ReportLayoutFile
		{
			get 
			{
				return mstrReportLayoutFile;
			}
			set
			{
				mstrReportLayoutFile = value;
			}
		}


		public object Invoke(string pstrMethod, object[] pobjParameters)
		{
			return this.GetType().InvokeMember(pstrMethod, BindingFlags.InvokeMethod, null, this, pobjParameters);
		}

		public DataTable ExecuteReport(string pstrSaleOrderDetailID, string pstrProductionLineID, string pstrFullname)
		{
			DataTable dtbReportData = GetReportData(pstrSaleOrderDetailID, pstrProductionLineID, pstrFullname);
			int i = 0;
			foreach (DataRow drData in dtbReportData.Rows)
			{
				i++;
				drData["Code"] = drData["Code"].ToString() + i.ToString("000");
			} 
			return dtbReportData;
		}

		private DataTable GetReportData(string pstrSaleOrderDetailID, string pstrProductionLineID, string pstrFullname)
		{
			OleDbConnection cn = null;
			try
			{
				cn = new OleDbConnection(mConnectionString);
				DataTable dtbItem = new DataTable();
				string strSql = " SELECT DISTINCT SUBSTRING(FGoodsCode, LEN(FGoodsCode) - 1, 2) + SUBSTRING(FGoodsCode, 1, 4) + ISNULL(PL.Code,'') AS Code,"
					+ " FGoodsCode, SP.Code + '(' + SP.Description + ')' Product, WOQuantity,"
					+ " P.Group1, P.Group2, P.GroupQuantity, "
					+ " CASE ISNULL(WC.Code,'') WHEN '' THEN P.Code"
					+ " ELSE SUBSTRING(P.Code, 1, LEN(P.Code) - LEN(WC.Code)-1)"
					+ " END PartNo, P.Description PartName, "
					+ " COM.Code ComponentNo, COM.Description ComponentName, UM.Code Unit, IOB.Quantity ComponentQty, IOB.Quantity * ISNULL(COM.Rate,1) Weight,"
					+ " getdate() ServerDate, N'" + pstrFullname + "' AS Fullname"
					+ " FROM SO_SaleOrderDetail SD JOIN ITM_Product SP ON SD.ProductID = SP.ProductID"
					+ " JOIN ITM_BOM IB ON SP.ProductID = IB.ProductID"
					+ " JOIN ITM_Product P ON IB.ComponentID = P.ProductID"
					+ " JOIN ITM_BOM IOB ON P.ProductID = IOB.ProductID"
					+ " JOIN ITM_Product COM ON IOB.ComponentID = COM.ProductID"
					+ " LEFT JOIN MST_WorkCenter WC ON P.WorkCenterID = WC.WorkCenterID"
					+ " LEFT JOIN PRO_ProductionLine PL ON P.ProductionLineID = PL.ProductionLineID"
					+ " LEFT JOIN MST_UnitOfMeasure UM ON UM.UnitOfMeasureID = COM.DesignUMID"
					+ " WHERE ISNULL(COM.MakeItem,0) = 0"
					+ " AND ISNULL(P.ProductTypeID,0) <> 3"
					+ " AND SD.SaleOrderDetailID = " + pstrSaleOrderDetailID;
				if (pstrProductionLineID.Length != 0)
					strSql += " AND P.ProductionLineID = " + pstrProductionLineID;
				OleDbDataAdapter odad = new OleDbDataAdapter(strSql, cn);
				odad.Fill(dtbItem);
				return dtbItem;
			}
			finally
			{
				if (cn != null)
					if (cn.State != ConnectionState.Closed)
						cn.Close();
			}
		}
	}
}